home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xmball / xmmball.c < prev   
C/C++ Source or Header  |  1996-02-07  |  18KB  |  594 lines

  1. /*
  2. # MOTIF-BASED MASTERBALL(tm)
  3. #
  4. #  xmmball.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 5: 95/10/02 Xt/Motif
  28.   Version 1: 94/09/15 Xt
  29. */
  30.  
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #ifdef VMS
  34. #include <unixlib.h>
  35. #define getlogin cuserid
  36. #else
  37. #ifndef apollo
  38. #include <unistd.h>
  39. #endif
  40. #endif
  41. #include <X11/Intrinsic.h>
  42. #include <X11/StringDefs.h>
  43. #include <X11/Shell.h>
  44. #include <X11/cursorfont.h>
  45. #include <Xm/PanedW.h>
  46. #include <Xm/RowColumn.h>
  47. #include <Xm/Label.h>
  48. #include <Xm/LabelG.h>
  49. #include <Xm/Scale.h>
  50. #include <Xm/ToggleB.h>
  51. #include <Xm/ToggleBG.h>
  52. #include "Mball.h"
  53. #include "mball.xbm"
  54. #include "mouse-l.xbm"
  55. #include "mouse-r.xbm"
  56.  
  57. #ifndef SCOREFILE
  58. #define SCOREFILE "/usr/games/lib/mball.scores"
  59. #endif
  60.  
  61. /* The following are in MballP.h also */
  62. #define MINWEDGES 2
  63. #define MAXWEDGES 8
  64. #define MINRINGS 1
  65.  
  66. #define MAXRINGS 6
  67. #define MAXRECORD 32767
  68.  
  69. static void Initialize();
  70. static void CallbackMball();
  71.  
  72. static void PrintRecord();
  73. static int HandleSolved();
  74. static void ReadRecords();
  75. static void WriteRecords();
  76.  
  77. static void WedgeToggle();
  78. static void RingSlider();
  79. static void OrientToggle();
  80. static void PracticeToggle();
  81. static void motif_printf();
  82.  
  83. static Arg arg[5];
  84. static Widget moves, record, message, mball, orientSwitch, practiceSwitch,
  85.    wedge[(MAXWEDGES - MINWEDGES) / 2 + 1], ring;
  86. static int mballRecord[2][(MAXWEDGES - MINWEDGES) / 2 + 1]
  87.   [MAXRINGS - MINRINGS + 1];
  88. static int movesDsp = 0;
  89. static char messageDsp[128] = "Welcome";
  90.  
  91. static char *wedgeString[] = {
  92.   "Two", "Four", "Six", "Eight"
  93. };
  94.  
  95. static void usage()
  96. {
  97.   (void) fprintf(stderr, "usage: xmmball\n");
  98.   (void) fprintf(stderr,
  99.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  100.   (void) fprintf(stderr,
  101.     "\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
  102.   (void) fprintf(stderr,
  103.     "\t[-{border|bd} {color}] [-mono] [-{wedges {int}}] [-{rings {int}}]\n");
  104.   (void) fprintf(stderr,
  105.     "\t[-[no]orient] [-[no]practice] [-wedge{0|1|2|3|4|5|6|7} {color}]\n");
  106.   exit(1);
  107. }
  108.  
  109. static XrmOptionDescRec options[] = {
  110.   {"-fg",        "*mball.Foreground",    XrmoptionSepArg,    NULL},
  111.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  112.   {"-foreground",    "*mball.Foreground",    XrmoptionSepArg,    NULL},
  113.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  114.   {"-border",        "*mball.pieceBorder",    XrmoptionSepArg,    NULL},
  115.   {"-bd",        "*mball.pieceBorder",    XrmoptionSepArg,    NULL},
  116.   {"-mono",        "*mball.mono",        XrmoptionNoArg,        "TRUE"},
  117.   {"-wedges",        "*mball.wedges",    XrmoptionSepArg,    NULL},
  118.   {"-rings",        "*mball.rings",        XrmoptionSepArg,    NULL},
  119.   {"-orient",        "*mball.orient",    XrmoptionNoArg,        "TRUE"},
  120.   {"-noorient",        "*mball.orient",    XrmoptionNoArg,        "FALSE"},
  121.   {"-practice",        "*mball.practice",    XrmoptionNoArg,        "TRUE"},
  122.   {"-nopractice",    "*mball.practice",    XrmoptionNoArg,        "FALSE"},
  123.   {"-wedge0",        "*mball.wedgeColor0",    XrmoptionSepArg,    NULL},
  124.   {"-wedge1",        "*mball.wedgeColor1",    XrmoptionSepArg,    NULL},
  125.   {"-wedge2",        "*mball.wedgeColor2",    XrmoptionSepArg,    NULL},
  126.   {"-wedge3",        "*mball.wedgeColor3",    XrmoptionSepArg,    NULL},
  127.   {"-wedge4",        "*mball.wedgeColor4",    XrmoptionSepArg,    NULL},
  128.   {"-wedge5",        "*mball.wedgeColor5",    XrmoptionSepArg,    NULL},
  129.   {"-wedge6",        "*mball.wedgeColor6",    XrmoptionSepArg,    NULL},
  130.   {"-wedge7",        "*mball.wedgeColor7",    XrmoptionSepArg,    NULL},
  131. };
  132.  
  133. int main(argc, argv)
  134.   int argc;
  135.   char *argv[];
  136. {
  137.   Widget toplevel;
  138.   Widget panel, panel2, rowcol, rowcol2, rowcol3, rowcol4;
  139.   Pixmap mouseLeftCursor, mouseRightCursor;
  140.   Pixel fg, bg;
  141.   int i;
  142.  
  143.   toplevel = XtInitialize(argv[0], "Mball",
  144.     options, XtNumber(options), &argc, argv);
  145.   if (argc != 1)
  146.     usage();
  147.  
  148.   XtSetArg(arg[0], XtNiconPixmap,
  149.     XCreateBitmapFromData(XtDisplay(toplevel),
  150.       RootWindowOfScreen(XtScreen(toplevel)),
  151.       (char *) mball_bits, mball_width, mball_height));
  152.   XtSetArg(arg[1], XmNkeyboardFocusPolicy, XmPOINTER); /* not XmEXPLICIT */
  153.   XtSetValues(toplevel, arg, 2);
  154.   panel = XtCreateManagedWidget("panel", xmPanedWindowWidgetClass, toplevel,
  155.     NULL, 0);
  156.   panel2 = XtVaCreateManagedWidget("panel2", xmPanedWindowWidgetClass, panel,
  157.     XmNseparatorOn, False,
  158.     XmNsashWidth, 1,
  159.     XmNsashHeight, 1,
  160.     NULL);
  161.  
  162.   rowcol = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, panel2,
  163.     XmNnumColumns, 2,
  164.     XmNorientation, XmHORIZONTAL,
  165.     XmNpacking, XmPACK_COLUMN,
  166.     NULL);
  167.   XtVaGetValues(rowcol, XmNforeground, &fg, XmNbackground, &bg, NULL);
  168.   mouseLeftCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  169.     RootWindowOfScreen(XtScreen(rowcol)), mouse_left_bits,
  170.     mouse_left_width, mouse_left_height, fg, bg,
  171.     DefaultDepthOfScreen(XtScreen(rowcol)));
  172.   mouseRightCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  173.     RootWindowOfScreen(XtScreen(rowcol)), mouse_right_bits,
  174.     mouse_right_width, mouse_right_height, fg, bg,
  175.     DefaultDepthOfScreen(XtScreen(rowcol)));
  176.   XtVaCreateManagedWidget("mouseLeftText", xmLabelGadgetClass, rowcol,
  177.     XtVaTypedArg, XmNlabelString, XmRString, "Move", 5, NULL);
  178.   XtVaCreateManagedWidget("mouseLeft", xmLabelGadgetClass, rowcol,
  179.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseLeftCursor, NULL);
  180.   XtVaCreateManagedWidget("mouseRightText", xmLabelGadgetClass, rowcol,
  181.     XtVaTypedArg, XmNlabelString, XmRString, "Randomize", 10, NULL);
  182.   XtVaCreateManagedWidget("mouseRight", xmLabelGadgetClass, rowcol,
  183.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseRightCursor, NULL);
  184.   XtVaCreateManagedWidget("CallbackMball", xmLabelGadgetClass, rowcol,
  185.     XtVaTypedArg, XmNlabelString, XmRString, "Moves", 6, NULL);
  186.   moves = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  187.   XtVaCreateManagedWidget("recordText", xmLabelGadgetClass, rowcol,
  188.     XtVaTypedArg, XmNlabelString, XmRString, "Record", 7, NULL);
  189.   record = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  190.  
  191.   rowcol2 = XtVaCreateManagedWidget("Rowcol2", xmRowColumnWidgetClass, panel2,
  192.     XmNnumColumns, 1,
  193.     XmNorientation, XmHORIZONTAL,
  194.     XmNpacking, XmPACK_COLUMN,
  195.     XmNradioBehavior, True,
  196.     NULL);
  197.   for (i = 0; i < XtNumber(wedgeString); i++) {
  198.     wedge[i] = XtVaCreateManagedWidget(wedgeString[i],
  199.       xmToggleButtonGadgetClass, rowcol2,
  200.       XmNradioBehavior, True,
  201.       NULL);
  202.     XtAddCallback(wedge[i], XmNvalueChangedCallback, WedgeToggle,
  203.       (XtPointer) i);
  204.   }
  205.  
  206.   rowcol3 = XtVaCreateManagedWidget("Rowcol3", xmRowColumnWidgetClass, panel2,
  207.     NULL);
  208.   XtVaCreateManagedWidget("WedgeText", xmLabelGadgetClass, rowcol3,
  209.     XtVaTypedArg, XmNlabelString, XmRString, "Wedges", 7, NULL);
  210.   XtVaGetValues(rowcol3, XmNforeground, &fg, XmNbackground, &bg, NULL);
  211.   ring = XtVaCreateManagedWidget("ring", xmScaleWidgetClass, rowcol3,
  212.     XtVaTypedArg, XmNtitleString, XmRString, "Rings", 6,
  213.     XmNminimum, MINRINGS,
  214.     XmNmaximum, MAXRINGS,
  215.     XmNvalue, MINRINGS,
  216.     XmNshowValue, True,
  217.     XmNorientation, XmHORIZONTAL,
  218.     NULL);
  219.   XtAddCallback(ring, XmNvalueChangedCallback, RingSlider, NULL);
  220.   rowcol4 = XtVaCreateManagedWidget("Rowcol4", xmRowColumnWidgetClass, rowcol3,
  221.     XmNnumColumns, 1,
  222.     XmNorientation, XmHORIZONTAL,
  223.     XmNpacking, XmPACK_COLUMN,
  224.     NULL);
  225.   orientSwitch = XtVaCreateManagedWidget ("Orient",
  226.     xmToggleButtonWidgetClass, rowcol4,
  227.     NULL);
  228.   XtAddCallback(orientSwitch, XmNvalueChangedCallback, OrientToggle, NULL);
  229.   practiceSwitch = XtVaCreateManagedWidget ("Practice",
  230.     xmToggleButtonWidgetClass, rowcol4,
  231.     NULL);
  232.   XtAddCallback(practiceSwitch, XmNvalueChangedCallback, PracticeToggle, NULL);
  233.   message = XtVaCreateManagedWidget("Play Masterball! (use mouse and keypad)",
  234.     xmLabelWidgetClass, rowcol3,
  235.     NULL);
  236.  
  237.   mball = XtCreateManagedWidget("mball", mballWidgetClass, panel,
  238.     NULL, 0);
  239.   XtAddCallback(mball, XtNselectCallback, CallbackMball, NULL);
  240.   Initialize(mball);
  241.   XtRealizeWidget(toplevel);
  242.   XGrabButton(XtDisplay(mball), AnyButton, AnyModifier, XtWindow(mball),
  243.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  244.     GrabModeAsync, GrabModeAsync, XtWindow(mball),
  245.     XCreateFontCursor(XtDisplay(mball), XC_crosshair));
  246.   XtMainLoop();
  247.  
  248. #ifdef VMS
  249.   return 1;
  250. #else
  251.   return 0;
  252. #endif
  253. }
  254.  
  255. static void Initialize(w)
  256.   Widget w;
  257. {
  258.   int wedges, rings;
  259.   Boolean orient, practice;
  260.  
  261.   XtVaSetValues(w,
  262.     XtNstart, FALSE,
  263.     NULL);
  264.   XtVaGetValues(w,
  265.     XtNwedges, &wedges,
  266.     XtNrings, &rings,
  267.     XtNorient, &orient,
  268.     XtNpractice, &practice,
  269.     NULL);
  270.   XmToggleButtonSetState(wedge[(wedges - MINWEDGES) / 2], True, False);
  271.   if (rings <= MAXRINGS)
  272.     XmScaleSetValue(ring, rings);
  273.   XmToggleButtonSetState(orientSwitch, orient, True);
  274.   XmToggleButtonSetState(practiceSwitch, practice, True);
  275.   ReadRecords();
  276.   PrintRecord(wedges, rings, orient, practice);
  277. }
  278.  
  279. static void CallbackMball(w, clientData, callData)
  280.   Widget w;
  281.   caddr_t clientData;
  282.   mballCallbackStruct *callData;
  283. {
  284.   int wedges, rings;
  285.   Boolean orient, practice, start;
  286.  
  287.   XtVaGetValues(w,
  288.     XtNwedges, &wedges,
  289.     XtNrings, &rings,
  290.     XtNorient, &orient,
  291.     XtNpractice, &practice,
  292.     XtNstart, &start,
  293.     NULL);
  294.   (void) strcpy(messageDsp, "");
  295.   switch (callData->reason) {
  296.     case MBALL_RESTORE:
  297.       if (practice)
  298.         motif_printf(record, "practice");
  299.       movesDsp = 0;
  300.       break;
  301.     case MBALL_RESET:
  302.       movesDsp = 0;
  303.       break;
  304.     case MBALL_AMBIGUOUS:
  305.       (void) strcpy(messageDsp, "Ambiguous move");
  306.       break;
  307.     case MBALL_ILLEGAL:
  308.       if (practice || start)
  309.         (void) strcpy(messageDsp, "Illegal move");
  310.       else
  311.         (void) strcpy(messageDsp, "Randomize to start");
  312.       break;
  313.     case MBALL_MOVED:
  314.       movesDsp++;
  315.       XtSetArg(arg[0], XtNstart, TRUE);
  316.       XtSetValues(w, arg, 1);
  317.       break;
  318.     case MBALL_CONTROL:
  319.       return;
  320.     case MBALL_SOLVED:
  321.       if (practice)
  322.         movesDsp = 0;
  323.       else { 
  324.         if (HandleSolved(movesDsp, wedges, rings, orient))
  325.           (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  326.         else
  327.           (void) strcpy(messageDsp, "Solved!");
  328.       }
  329.       XtSetArg(arg[0], XtNstart, FALSE);
  330.       XtSetValues(w, arg, 1);
  331.       break;
  332.     case MBALL_PRACTICE:
  333.       movesDsp = 0;
  334.       practice = !practice;
  335.       if (!practice)
  336.         (void) strcpy(messageDsp, "Randomize to start");
  337.       PrintRecord(wedges, rings, orient, practice);
  338.       XtSetArg(arg[0], XtNpractice, practice);
  339.       XtSetArg(arg[1], XtNstart, FALSE);
  340.       XtSetValues(w, arg, 2);
  341.       XmToggleButtonSetState(practiceSwitch, practice, True);
  342.       break;
  343.     case MBALL_RANDOMIZE:
  344.       movesDsp = 0;
  345.       XtSetArg(arg[0], XtNpractice, FALSE);
  346.       XtSetArg(arg[1], XtNstart, FALSE);
  347.       XtSetValues(w, arg, 2);
  348.       break; 
  349.     case MBALL_DEC:
  350.       movesDsp = 0;
  351.       rings--;
  352.       PrintRecord(wedges, rings, orient, practice);
  353.       XtSetArg(arg[0], XtNrings, rings);
  354.       XtSetValues(w, arg, 1);
  355.       if (rings <= MAXRINGS)
  356.         XmScaleSetValue(ring, rings);
  357.       break;
  358.    case MBALL_ORIENT:
  359.       movesDsp = 0;
  360.       orient = !orient;
  361.       PrintRecord(wedges, rings, orient, practice);
  362.       XtSetArg(arg[0], XtNorient, orient);
  363.       XtSetValues(w, arg, 1);
  364.       XmToggleButtonSetState(orientSwitch, orient, True);
  365.       break;
  366.     case MBALL_INC:
  367.       movesDsp = 0;
  368.       rings++;
  369.       PrintRecord(wedges, rings, orient, practice);
  370.       XtSetArg(arg[0], XtNrings, rings);
  371.       XtSetValues(w, arg, 1);
  372.       if (rings <= MAXRINGS)
  373.         XmScaleSetValue(ring, rings);
  374.       break;
  375.     case MBALL_WEDGE2:
  376.     case MBALL_WEDGE4:
  377.     case MBALL_WEDGE6:
  378.     case MBALL_WEDGE8:
  379.       movesDsp = 0;
  380.       wedges = 2 * (callData->reason - MBALL_WEDGE2) + MINWEDGES;
  381.       PrintRecord(wedges, rings, orient, practice);
  382.       XtSetArg(arg[0], XtNwedges, wedges);
  383.       XtSetValues(w, arg, 1);
  384.       XmToggleButtonSetState(wedge[(wedges - MINWEDGES) / 2], True, True);
  385.       break;
  386.     case MBALL_COMPUTED:
  387.       XtSetArg(arg[0], XtNstart, FALSE);
  388.       XtSetValues(w, arg, 1);
  389.       break;
  390.     case MBALL_UNDO:
  391.       movesDsp--;
  392.       XtSetArg(arg[0], XtNstart, TRUE);
  393.       XtSetValues(w, arg, 1);
  394.       break;
  395.   }
  396.   motif_printf(message, "%s", messageDsp);
  397.   motif_printf(moves, "%d", movesDsp);
  398. }
  399.  
  400. static void WedgeToggle(w, bit, cbs)
  401.   Widget w;
  402.   int bit;
  403.   XmToggleButtonCallbackStruct *cbs;
  404. {
  405.   int wedges, rings;
  406.   Boolean orient, practice;
  407.  
  408.   if (cbs->set) {
  409.     XtVaGetValues(mball,
  410.       XtNrings, &rings,
  411.       XtNorient, &orient,
  412.       XtNpractice, &practice,
  413.       NULL);
  414.     wedges = bit * 2 + MINWEDGES;
  415.     XtVaSetValues(mball,
  416.       XtNwedges, wedges,
  417.       NULL);
  418.     movesDsp = 0;
  419.     motif_printf(moves, "%d", movesDsp);
  420.     PrintRecord(wedges, rings, orient, practice);
  421.   }
  422. }
  423.  
  424. static void RingSlider(w, clientData, cbs)
  425.   Widget w;
  426.   XtPointer clientData;
  427.   XmScaleCallbackStruct *cbs;
  428. {
  429.   int wedges, rings = cbs->value, old;
  430.   Boolean orient, practice;
  431.  
  432.   XtVaGetValues(mball,
  433.     XtNwedges, &wedges,
  434.     XtNrings, &old,
  435.     XtNorient, &orient,
  436.     XtNpractice, &practice,
  437.     NULL);
  438.   if (old != rings) {
  439.     XtVaSetValues(mball,
  440.       XtNrings, rings,
  441.       NULL);
  442.     movesDsp = 0;
  443.     motif_printf(moves, "%d", movesDsp);
  444.     PrintRecord(wedges, rings, orient, practice);
  445.   }
  446. }
  447.  
  448. static void OrientToggle(w, clientData, cbs)
  449.   Widget w;
  450.   XtPointer clientData;
  451.   XmToggleButtonCallbackStruct *cbs;
  452. {
  453.   int wedges, rings;
  454.   Boolean orient = cbs->set, practice;
  455.  
  456.   XtVaSetValues(mball,
  457.     XtNorient, orient,
  458.     NULL);
  459.   XtVaGetValues(mball,
  460.     XtNwedges, &wedges,
  461.     XtNrings, &rings,
  462.     XtNpractice, &practice,
  463.     NULL);
  464.   movesDsp = 0;
  465.   motif_printf(moves, "%d", movesDsp);
  466.   PrintRecord(wedges, rings, orient, practice);
  467. }
  468.  
  469. static void PracticeToggle(w, clientData, cbs)
  470.   Widget w;
  471.   XtPointer clientData;
  472.   XmToggleButtonCallbackStruct *cbs;
  473. {
  474.   int wedges, rings;
  475.   Boolean orient, practice = cbs->set;
  476.  
  477.   XtVaSetValues(mball,
  478.     XtNpractice, practice,
  479.     XtNstart, FALSE,
  480.     NULL);
  481.   XtVaGetValues(mball,
  482.     XtNwedges, &wedges,
  483.     XtNrings, &rings,
  484.     XtNorient, &orient,
  485.     NULL);
  486.   movesDsp = 0;
  487.   motif_printf(moves, "%d", movesDsp);
  488.   if (!practice)
  489.     (void) strcpy(messageDsp, "Randomize to start");
  490.   PrintRecord(wedges, rings, orient, practice);
  491. }
  492.  
  493. static void PrintRecord(wedges, rings, orient, practice)
  494.   int wedges, rings;
  495.   Boolean orient, practice;
  496. {
  497.   int i = (orient) ? 1 : 0;
  498.   int w = (wedges - MINWEDGES) / 2;
  499.   int r = rings - MINRINGS;
  500.  
  501.   if (practice)
  502.     motif_printf(record, "practice");
  503.   else if (rings > MAXRINGS)
  504.     motif_printf(record, "NOT RECORDED");
  505.   else if (mballRecord[i][w][r] >= MAXRECORD)
  506.     motif_printf(record, "NEVER");
  507.   else
  508.     motif_printf(record, "%d", mballRecord[i][w][r]);
  509. }
  510.  
  511. static int HandleSolved(counter, wedges, rings, orient)
  512.   int counter, wedges, rings;
  513.   Boolean orient;
  514. {
  515.   int i = (orient) ? 1 : 0;
  516.   int w = (wedges - MINWEDGES) / 2;
  517.   int r = rings - MINRINGS;
  518.  
  519.   if (rings <= MAXRINGS && counter < mballRecord[i][w][r]) {
  520.     mballRecord[i][w][r] = counter;
  521.     if (orient && (mballRecord[i][w][r] < mballRecord[!i][w][r]))
  522.       mballRecord[!i][w][r] = counter;
  523.     WriteRecords();
  524.     PrintRecord(wedges, rings, orient, False);
  525.     return TRUE;
  526.   }
  527.   return FALSE;
  528. }
  529.  
  530. static void ReadRecords()
  531. {
  532.   FILE *fp;
  533.   int i, j, n, orient;
  534.  
  535.   for (orient = 0; orient < 2; orient++)
  536.     for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++)
  537.       for (j = 0; j < MAXRINGS - MINRINGS + 1; j++)
  538.         mballRecord[orient][i][j] = MAXRECORD;
  539.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  540.     motif_printf(message, "Can not open %s, taking defaults.", SCOREFILE);
  541.   else {
  542.     for (orient = 0; orient < 2; orient++)
  543.       for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++)
  544.         for (j = 0; j < MAXRINGS - MINRINGS + 1; j++) {
  545.           (void) fscanf(fp, "%d", &n);
  546.           mballRecord[orient][i][j] = n;
  547.         }
  548.     (void) fclose(fp);
  549.   }
  550. }
  551.  
  552. static void WriteRecords()
  553. {
  554.   FILE *fp;
  555.   int i, j, orient;
  556.  
  557.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  558.     motif_printf(message, "Can not write to %s.", SCOREFILE);
  559.   else {
  560.     for (orient = 0; orient < 2; orient++) {
  561.       for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++) {
  562.         for (j = 0; j < MAXRINGS - MINRINGS + 1; j++)
  563.           (void) fprintf(fp, "%d ", mballRecord[orient][i][j]);
  564.         (void) fprintf(fp, "\n");
  565.       }
  566.       (void) fprintf(fp, "\n");
  567.     }
  568.     (void) fclose(fp);
  569.   }
  570. }
  571.  
  572. #include <varargs.h>
  573. static void motif_printf(va_alist)
  574.   va_dcl
  575. {
  576.   Widget w;
  577.   char *format;
  578.   va_list args;
  579.   char str[1000];
  580.   Arg wargs[10];
  581.   XmString xmstr;
  582.  
  583.   va_start(args);
  584.   w = va_arg(args, Widget);
  585.   if (!XtIsSubclass(w, xmLabelWidgetClass))
  586.     XtError("motif_printf() requires a Label Widget");
  587.   format = va_arg(args, char *);
  588.   (void) vsprintf(str, format, args);
  589.   xmstr = XmStringCreateLtoR(str, XmSTRING_DEFAULT_CHARSET);
  590.   XtSetArg(wargs[0], XmNlabelString, xmstr);
  591.   XtSetValues(w, wargs, 1);
  592.   va_end(args);
  593. }
  594.